package logiclib

import (
	"MqttCloudProtocolServer/publiclib/helplib"
	"os/exec"
	"time"

	"github.com/shirou/gopsutil/process"

	"github.com/wonderivan/logger"
)

//ProcessStatue 进程状态
type ProcessStatue int

const (
	//Stoped 停止
	Stoped ProcessStatue = iota
	//Stoping 停止中
	Stoping
	//Running 运行中
	Running
)

//ProcessBase 提供基本函数定义。需要集成实现
type ProcessBase struct {
	filePath string
	title    string
	//countMilsecond int
	//runningFlag   ProcessStatue
	runningStatue ProcessStatue
	cmd           *exec.Cmd
	isDaemon      bool
}

//SetIsDaemon fun
func (_this *ProcessBase) SetIsDaemon(isDaemon bool) {
	_this.isDaemon = isDaemon
}

//GetRunningStatue fun
func (_this *ProcessBase) GetRunningStatue() string {
	switch _this.runningStatue {
	case Stoped:
		return "Stoped"
	case Stoping:
		return "Stoping"
	case Running:
		return "Running"
	default:
		return "Error Statue"
	}
}

//GetTitle Fun
func (_this *ProcessBase) GetTitle() string {
	return _this.title
}

//SetTitle Fun
func (_this *ProcessBase) SetTitle(title string) {
	_this.title = title
}

//Init Fun
func (_this *ProcessBase) Init() {
	_this.isDaemon = true
	//_this.runningFlag = Stoped
	_this.runningStatue = Stoped
}

//GetFilePath Fun
func (_this *ProcessBase) GetFilePath() string {
	return _this.filePath
}

//SetFilePath Fun
func (_this *ProcessBase) SetFilePath(path string) {
	_this.filePath = path
}

//IsExist
func IsExist(pName string) (bool, []int32) {
	var pidres []int32
	pids, _ := process.Pids()
	for _, p := range pids {
		pn, _ := process.NewProcess(p)
		pname, _ := pn.Name()
		if pname == pName {
			pidres = append(pidres, p)
		}
	}
	return len(pidres) > 0, pidres
}

//KillProcess
func KillProcess(pids []int32) {
	for _, id := range pids {
		p, _ := process.NewProcess(id)
		p.Kill()
	}
}

//KillIfExist
func KillIfExist(pName string) {
	res, ids := IsExist(pName)
	if res {
		KillProcess(ids)
	}
}

//Start Fun
func (_this *ProcessBase) Start() bool {
	var err error
	if exit, _ := helplib.FileExists(_this.GetFilePath()); !exit {
		logger.Alert(_this.title + "进程文件不存在")
		_this.isDaemon = false
		return false
	}
	logger.Debug(_this.title + "进程文件存在")
	//_this.runningFlag = Running
	_this.cmd = exec.Command(_this.GetFilePath(), "-child-process")
	logger.Info(_this.title + "进程文件启动")
	err = _this.cmd.Start()
	if err == nil {
		_this.runningStatue = Running
	}
	return true
}

//Wait Fun
func (_this *ProcessBase) Wait() {
	for {
		if _this.runningStatue == Running {
			err := _this.cmd.Wait()
			if err != nil {
				logger.Alert(err)
			}
		}
		_this.runningStatue = Stoped
		if _this.isDaemon {
			time.Sleep(time.Second)
			_this.Start()
			_this.runningStatue = Running
			/*if _this.runningFlag == Running {
				time.Sleep(time.Second)
				_this.Start()
				_this.runningStatue = Running
			} else {
				time.Sleep(time.Second)
				_this.runningStatue = Stoped
				//_this.runningFlag = Stoped
			}*/
		} else {
			_this.runningStatue = Stoped
			//_this.runningFlag = Stoped
			break
		}
	}
}

//Stop Fun
func (_this *ProcessBase) Stop() bool {
	/*_this.isDaemon = false
	_this.runningFlag = Stoping
	for _this.runningFlag == Stoping {
		time.Sleep(time.Millisecond * 100)
	}*/
	//_this.runningFlag = Stoped
	_this.runningStatue = Stoped

	time.Sleep(time.Millisecond * 300)
	for _this.cmd != nil && _this.cmd.Process != nil && !(_this.cmd.ProcessState.Exited() || _this.cmd.ProcessState.Success()) {
		time.Sleep(time.Millisecond * 300)
		_this.cmd.Process.Kill()
		_this.runningStatue = Stoped
		return false
	}
	//_this.runningFlag = Stoped
	return true
}
